use std::{env, path::PathBuf, str::FromStr};

use lazy_static::lazy_static;
use log::{error, info, warn};
use vsse::SearchConfig;

pub const SERVER_CONFIG_PATH: &str = "./config.yaml";
pub const EMBEDDING_MODEL_PATH: &str = "../embd/model/text2vec-base-chinese_safetensors";
pub const CONTENT_STORE_PATH: &str = "../vsse/materials/contentstore.json";
pub const SIMPLE_ENGINE_INDEX: &str = "../vsse/materials/se_index.json";

lazy_static! {
    pub static ref SERVER_CONFIG: crate::config::Config = {
        use crate::config::Config;
        let path = env::var("LYRICS_SERVER_CONFIG_PATH").unwrap_or({
            info!(
                "Environment variable `LYRICS_SERVER_CONFIG_PATH` not found.Use default : {}",
                SERVER_CONFIG_PATH
            );
            SERVER_CONFIG_PATH.into()
        });
        let path = PathBuf::from_str(SERVER_CONFIG_PATH)
            .map_err(|e| {
                error!("Config path : {} invalied.", SERVER_CONFIG_PATH);
                e
            })
            .unwrap();
        let config = if !path.exists() {
            warn!("Config file is not exist.Try creating...");
            let default_config = Config::default();
            default_config
                .save_yaml_file(&path)
                .map_err(|e| {
                    error!(
                        "Failed to create default config file at {:?}. Error : {}",
                        path, e
                    );
                    e
                })
                .unwrap();
            info!("Using default config : {:?}", default_config);
            default_config
        } else {
            let config = Config::from_yaml_file(SERVER_CONFIG_PATH)
                .map_err(|e| {
                    error!("Failed to load config.Error : {}", e);
                    e
                })
                .unwrap();
            config
        };
        config
    };
}
lazy_static! {
    pub static ref CONTENT_STORE: vsse::content::ContentStore = {
        info!("Loading content store.");
        use vsse::content::ContentStore;
        let store = ContentStore::from_json_file(&SERVER_CONFIG.content_store_path).unwrap();
        store
    };
    pub static ref SIMPLE_ENGINE: vsse::engine::VecEngineImpl<vsse::engine::simple::SimpleEngine, embd::Embd> = {
        info!("Loading simple engine.");
        use embd::Embd;
        use vsse::engine::{
            simple::{InitConfig, SimpleEngine},
            VecEngine, VecEngineBuilder, VecEngineImpl,
        };

        let init_config = InitConfig {
            path: SIMPLE_ENGINE_INDEX.into(),
        };
        let engine = VecEngineImpl::<SimpleEngine, Embd>::new_with_embedding_model_config::<
            SimpleEngine,
            InitConfig,
        >(&init_config, &SERVER_CONFIG.embedding_model_config)
        .map_err(|e| {
            error!("Failed to load simple engine.Error : {}", e);
            e
        })
        .unwrap();
        engine
    };
}

lazy_static! {
    pub static ref DEFAULT_SEARCH_CONFIG: SearchConfig =
        SERVER_CONFIG.default_search_config.clone();
}
